package api.extractExpert;

import base.BaseEntity;
import com.baidu.unbiz.fluentvalidator.ComplexResult;
import com.baidu.unbiz.fluentvalidator.FluentValidator;
import com.baidu.unbiz.fluentvalidator.ResultCollectors;
import common.BaseController;
import common.CommonResult;
import common.validateUser.InterfaceUsers;
import common.validateUser.ValidateUserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import services.business.BusinessInfoServices;
import services.business.BusinessMajorServices;
import services.dictionary.ItemTypeServices;
import services.dictionary.MajorTypeServices;
import services.expertInfo.ExpertMajorServices;
import services.specific.ExtractExpertServices;
import services.staff.StaffInfoServices;
import util.DateUtil;
import util.RandomUtil;
import validator.NotBlankFluentValidator;
import validator.NotNullFluentValidator;
import wt.entity.business.BusinessInfo;
import wt.entity.business.BusinessMajor;
import wt.entity.dictionary.MajorType;
import wt.entity.expertInfo.ExpertMajor;
import wt.entity.specific.ExtractExpert;

import java.util.*;

/**
 * Created by Administrator on 2017/8/16.
 */
@Controller
@RequestMapping("httpApi")
public class AutomaticExtractionExpertController extends BaseController {
    @Autowired
    public InterfaceUsers interfaceUsers;
    @Autowired
    ItemTypeServices itemTypeServices;
    @Autowired
    BusinessInfoServices businessInfoServices;
    @Autowired
    StaffInfoServices staffInfoServices;
    @Autowired
    MajorTypeServices majorTypeServices;
    @Autowired
    ExtractExpertServices extractExpertServices;
    @Autowired
    BusinessMajorServices businessMajorServices;
    @Autowired
    ExpertMajorServices expertMajorServices;

    /**
     * 自动抽取
     *
     * @param
     * @param uid
     * @param sign
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "jianYan/automaticExtractionExpert", produces = "application/json;charset=UTF-8")
    public CommonResult jianYanAutomaticExtractionExpert(
            String uid,
            Long timeStamp,
            String sign,
            Integer count,
            String leaderGradeList,
            String affiliateCompany,
            String businessCode,
            @DateTimeFormat(pattern = DateUtil.DATE_PATTEN) Date startTime,
            @DateTimeFormat(pattern = DateUtil.DATE_PATTEN) Date endTime
    ) throws Exception {


        ComplexResult complexResult = FluentValidator.checkAll().failOver()
                .on(uid, new NotBlankFluentValidator("uid"))
                .on(timeStamp, new NotNullFluentValidator("timeStamp"))
                .on(sign, new NotBlankFluentValidator("sign"))
//                .on(count, new NotNullFluentValidator("count"))
                .on(businessCode, new NotBlankFluentValidator("businessCode"))
                .on(leaderGradeList, new NotBlankFluentValidator("leaderGradeList"))
                .on(startTime, new NotNullFluentValidator("startTime"))
                .on(endTime, new NotNullFluentValidator("endTime"))
                .doValidate()
                .result(ResultCollectors.toComplex());
        if (!complexResult.isSuccess()) {
            CommonResult commonResult = new CommonResult();
            commonResult.addMessage(complexResult);
            commonResult.setCode(CommonResult.ZJ005);
            return commonResult;
        }

        CommonResult commonResult = ValidateUserUtil.validateUser(uid, timeStamp, sign, interfaceUsers);  //用户验证
        if (!CommonResult.ZJ001.equals(commonResult.getCode())) {
            return commonResult;
        }


        BusinessInfo businessInfo = businessInfoServices.selectByBusinessCode(businessCode);
        if (businessInfo == null) {
            commonResult.setMessage(CommonResult.ZJ005_M);
            commonResult.setCode(CommonResult.ZJ005);
            return commonResult;
        }
        List<String> leaderGradeListHandle = Arrays.asList(leaderGradeList.trim().split(","));


        List<BusinessMajor> businessMajorList = businessMajorServices.selectByBusinessId(businessInfo.getId());
        List<String> majorNumList = new ArrayList<String>();//获取业务的专业编号
        for (BusinessMajor businessMajor : businessMajorList) {
            majorNumList.add(businessMajor.getMajorNum());
        }
        List<MajorType> majorTypeList = majorTypeServices.selectByMajorNumList(majorNumList);
        List<String> majorTypeIdList = BaseEntity.getIdList(majorTypeList);//获取业务的专业Id


        List<ExtractExpert> extractExpertList = extractExpertServices.selectAutomaticExtractExpert(null, null, Arrays.asList("AA", "A", "B", "C"), null, businessInfo.getItemId(), affiliateCompany, startTime, endTime);
        Map<String, ExtractExpert> expertMap = new HashMap<String, ExtractExpert>();

        for (ExtractExpert extractExpert : extractExpertList) {
            expertMap.put(extractExpert.getId(), extractExpert);
        }

        List<ExpertMajor> expertMajorList = expertMajorServices.adminSelectByMajorIdList(majorTypeIdList);
        Set<String> majorIdSet = new HashSet<String>();
        Set<String> expertIdSet = new HashSet<String>();

        Set<String> expertIdTemp = expertMap.keySet();
        for (int i = 0; i < expertMajorList.size(); i++) {//去除不符合
            if (expertIdTemp.contains(expertMajorList.get(i).getExpertId())) {
                majorIdSet.add(expertMajorList.get(i).getMajorId());
                expertIdSet.add(expertMajorList.get(i).getExpertId());
            } else {
                expertMajorList.remove(i);
                i--;
            }
        }

        List<ExpertAndMajor> expertAndMajorList = new ArrayList<ExpertAndMajor>();
        for (String expertId : expertIdSet) {
            ExpertAndMajor expertAndMajor = new ExpertAndMajor();
            expertAndMajor.setExtractExpert(expertMap.get(expertId));
            for (ExpertMajor expertMajor : expertMajorList) {
                if (expertMajor.getExpertId().equals(expertId)) {
                    expertAndMajor.addExpertMajorId(expertMajor.getMajorId());
                }
            }
            expertAndMajorList.add(expertAndMajor);
        }

        List<ExtractExpert> finalExpertList = new ArrayList<ExtractExpert>();//最终专家组


        RandomUtil.randomList(expertAndMajorList);//打行乱顺序
        Collections.sort(expertAndMajorList);//排序



        int majorCount=majorIdSet.size();
        for (int i = 0; i < expertAndMajorList.size(); i++) { //确定组长
            ExpertAndMajor expertAndMajor=expertAndMajorList.get(i);
            ExtractExpert leader = expertAndMajor.getExtractExpert();
            if (leaderGradeListHandle.contains(leader.getGrade())) {
                finalExpertList.add(leader);
                expertAndMajorList.remove(i);
                for (ExpertAndMajor temp : expertAndMajorList) {
                    temp.removeExpertMajorId(expertAndMajor.getMajorIdSet());
                }
                majorCount -= expertAndMajor.getMajorIdSet().size();
                break;
            }
        }


        teamMember(expertAndMajorList, majorCount, finalExpertList);//确定组员


        List<Result> resultList = HandleResult.treatmentResult(finalExpertList);

        if (!finalExpertList.isEmpty()&&leaderGradeListHandle.contains(resultList.get(0).getGrade())){//标记组长
            resultList.get(0).setLeader(true);
        }

        commonResult.setData(resultList);
        commonResult.setMessage(CommonResult.ZJ001_M);
        commonResult.setCode(CommonResult.ZJ001);
        return commonResult;

    }


    private static void teamMember(List<ExpertAndMajor> expertAndMajorList, int majorCount, List<ExtractExpert> expertList) {

        if (majorCount <= 0 || expertAndMajorList == null || expertAndMajorList.isEmpty()) {
            return;
        }
        Collections.sort(expertAndMajorList);//排序
        ExpertAndMajor expertAndMajor = expertAndMajorList.remove(0);
        expertList.add(expertAndMajor.getExtractExpert());
        for (ExpertAndMajor temp : expertAndMajorList) {
            temp.removeExpertMajorId(expertAndMajor.getMajorIdSet());
        }
        majorCount -= expertAndMajor.getMajorIdSet().size();
        teamMember(expertAndMajorList, majorCount, expertList);

    }


    private static class ExpertAndMajor implements Comparable<ExpertAndMajor> {

        ExtractExpert extractExpert;
        Set<String> majorIdSet = new HashSet<String>();


        public int compareTo(ExpertAndMajor o) {
            return (o.getMajorIdSet() == null ? 0 : o.getMajorIdSet().size()) -
                    (majorIdSet == null ? 0 : majorIdSet.size());
        }

        public void addExpertMajorId(String majorId) {
            majorIdSet.add(majorId);
        }

        public void removeExpertMajorId(Set<String> majorIdSet) {
            for (String majorId : majorIdSet) {
                removeExpertMajorId(majorId);
            }
        }

        public void removeExpertMajorId(String majorId) {
            if (majorIdSet.contains(majorId)) {
                majorIdSet.remove(majorId);
            }
        }


        public Set<String> getMajorIdSet() {
            return majorIdSet;
        }

        public ExtractExpert getExtractExpert() {
            return extractExpert;
        }

        public void setExtractExpert(ExtractExpert extractExpert) {
            this.extractExpert = extractExpert;
        }
    }




    /**
     * 自动抽取
     *
     * @param data
     * @param uid
     * @param sign
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "gongXu/automaticExtractionExpert", produces = "application/json;charset=UTF-8")
    public CommonResult gongXuAutomaticExtractionExpert(
            String uid,
            Long timeStamp,
            String sign,
            Integer count,
            String leaderGradeList,
            String affiliateCompany,
            String businessCode,
            @DateTimeFormat(pattern = DateUtil.DATE_PATTEN) Date startTime,
            @DateTimeFormat(pattern = DateUtil.DATE_PATTEN) Date endTime
    ) throws Exception {


        ComplexResult complexResult = FluentValidator.checkAll().failOver()
                .on(uid, new NotBlankFluentValidator("uid"))
                .on(timeStamp, new NotNullFluentValidator("timeStamp"))
                .on(sign, new NotBlankFluentValidator("sign"))
                .on(businessCode, new NotBlankFluentValidator("businessCode"))
                .on(leaderGradeList, new NotBlankFluentValidator("leaderGradeList"))
                .on(startTime, new NotNullFluentValidator("startTime"))
                .on(endTime, new NotNullFluentValidator("endTime"))
                .doValidate()
                .result(ResultCollectors.toComplex());
        if (!complexResult.isSuccess()) {
            CommonResult commonResult = new CommonResult();
            commonResult.addMessage(complexResult);
            commonResult.setCode(CommonResult.ZJ005);
            return commonResult;
        }

        CommonResult commonResult = ValidateUserUtil.validateUser(uid, timeStamp, sign, interfaceUsers);  //用户验证
        if (!CommonResult.ZJ001.equals(commonResult.getCode())) {
            return commonResult;
        }


        BusinessInfo businessInfo = businessInfoServices.selectByBusinessCode(businessCode);
        if (businessInfo == null) {
            commonResult.setMessage(CommonResult.ZJ005_M);
            commonResult.setCode(CommonResult.ZJ005);
            return commonResult;
        }


        List<BusinessMajor> businessMajorList = businessMajorServices.selectByBusinessId(businessInfo.getId());
        List<String> majorNumList = new ArrayList<String>();
        for (BusinessMajor businessMajor : businessMajorList) {
            majorNumList.add(businessMajor.getMajorNum());
        }


        List<ExtractExpert> extractExpertList = extractExpertServices.selectAutomaticExtractExpert(null, null, Arrays.asList("AA", "A", "B", "C"), majorNumList, businessInfo.getItemId(),affiliateCompany, startTime, endTime);


        //重排序
        RandomUtil.randomList(extractExpertList);

        List<Result> resultList = HandleResult.treatmentResult(extractExpertList);

        //确定组长
        List<String> leaderGradeListHandle = Arrays.asList(leaderGradeList.trim().split(","));
        for (int i = 0; i < resultList.size(); i++) {
            Result result = resultList.get(i);
            if (leaderGradeListHandle.contains(result.getGrade())) {
                result.setLeader(true);
                resultList.set(i, resultList.get(0));
                resultList.set(0, result);
                break;
            }
        }

        if (count==null){
            commonResult.setData(resultList);
        }else{
            commonResult.setData(resultList.subList(0, resultList.size() >= count ? count : resultList.size()));
        }
        commonResult.setMessage(CommonResult.ZJ001_M);
        commonResult.setCode(CommonResult.ZJ001);
        return commonResult;

    }


}
